<html>
<head><title>Calculator</title></head>
<body>
<h1>Calculator</h1><br/>
<form method="GET">
<input type="text" name="expr"><input type="submit" value="Calculate">
</form>
<?php

function match_number($expr, $offset) {
  $pattern = "/\s*-{0,1}[0-9]*(\.[0-9]*|)\s*/";
  $num = preg_match($pattern, $expr, $matches, PREG_OFFSET_CAPTURE, $offset);
  // If no immediate match, then return NULL
  if ($num == 0 || $matches[0][1] != $offset) {
    return NULL;
  }
  else
    return $matches[0][0];
}

function match_operator($expr, $offset) {
  $pattern = "#\s*[-+*/]\s*#";
  $num = preg_match($pattern, $expr, $matches, PREG_OFFSET_CAPTURE, $offset);
  // If no immediate match, then return NULL
  if ($num == 0 || $matches[0][1] != $offset) {
    return NULL;
  }
  else
    return $matches[0][0];
}

if($_GET["expr"]){
  $expr = $_GET["expr"];
  $offset = 0;
  $valid = TRUE;
  $operator = "+";
  $divideByZero = FALSE;
  
  // Start by matching a number
  $match = match_number($expr, $offset);
  if ($match == NULL) {
    // force skip the loop
    $offset = strlen($expr);
    $valid = FALSE;
  }
  else
    $offset += strlen($match);
  $num = $match;
      
  while ($offset < strlen($expr)) {
    $match = match_operator($expr, $offset);
    if ($match == NULL) {
      $valid = FALSE;
      break;
    }
    $offset += strlen($operator);
    $operator = trim($match);
    
    $match = match_number($expr, $offset);
    if ($match == NULL) {
      $valid = FALSE;
      break;
    }
    $offset += strlen($match);
    $num = $match;
    if ($num == 0 && $operator == "/")
      $divideByZero = TRUE;    
  }
  
  if ($valid) {
    if ($divideByZero)
      echo $expr . " = ";
    else {
      eval("\$result = $expr;");
      echo $expr . " = " .$result;
    }
  }
  else
    echo "Invalid expression " . $expr;
  }
?>
</body>
</html>
